Skip to content

Fix Android startup crash: move TMPDIR off FUSE so Realm can mkfifo() - #233

Merged
winnerspiros merged 1 commit into
masterfrom
copilot/fix-apk-crash-issue-again
Apr 22, 2026
Merged

Fix Android startup crash: move TMPDIR off FUSE so Realm can mkfifo()#233
winnerspiros merged 1 commit into
masterfrom
copilot/fix-apk-crash-issue-again

Conversation

Copilot AI commented Apr 22, 2026

Copy link
Copy Markdown

APK crashes on every launch with RealmException: Failed to create fifo at '/storage/emulated/0/Android/data/sh.ppy.osulazer/files/lazer/realm_*.cv': Permission denied (13), thrown from RealmAccess..ctor before the file logger initialises (so no osu.log is ever written).

Root cause

RealmAccess.getConfiguration() sets:

FallbackPipePath = Path.Combine(Path.GetTempPath(), "lazer");

On Android, Path.GetTempPath() returns $TMPDIR. osu.Android/mono.env was setting TMPDIR to the app's external-files dir to make Mono's --jitmap perfmap user-retrievable — but that path is FUSE-backed, and the Linux kernel rejects mkfifo() on FUSE mounts with EACCES. Realm needs FIFOs for its cross-process notifier (.cv/.note), so Realm.GetInstance() throws on every startup. The diagnostic capture in build_test/archive.zip (three successive client_*_corrupt.realm files + empty logs/) confirmed RealmAccess's corrupt-recovery branch was firing on every launch and the crash was pre-logger.

Changes

  • osu.Android/mono.env: point TMPDIR at internal app cache (/data/user/0/sh.ppy.osulazer/cache), which is ext4/f2fs-backed and supports FIFOs. Document the FUSE/mkfifo constraint inline so this doesn't regress.
  • osu.Android/Native/crash_handler.cpp: update the perfmap-location comments to reflect the new TMPDIR. No code change — ensurePerfmapLoaded() already reads getenv("TMPDIR") at signal time, so JIT-frame symbolication keeps working; the symbolicated output still lands in native_crash.log in the external files dir, which remains user-retrievable.
  • osu.Android/osu.Android.csproj: refresh the <AndroidEnvironment> comment for the same reason.
  • build_test/: delete the diagnostic capture (archive.zip, native_crash.log, CMake leftovers) per request.

Note on the missing crash log

The user's report came via XamarinUncaughtExceptionHandler — a managed exception, not a native signal — so the native crash handler had nothing to capture and produced no native_crash.log. Future native crashes will still be captured normally once Realm initialises.

…s; remove build_test/

Agent-Logs-Url: https://github.com/winnerspiros/osu/sessions/7c477ddd-0d71-4e47-8c12-f431f48789c7

Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
@winnerspiros
winnerspiros marked this pull request as ready for review April 22, 2026 08:18
Copilot AI review requested due to automatic review settings April 22, 2026 08:18
@winnerspiros
winnerspiros merged commit 4d5f394 into master Apr 22, 2026
5 of 19 checks passed
@gitar-bot

gitar-bot Bot commented Apr 22, 2026

Copy link
Copy Markdown

Important

You are using the Gitar free plan. Upgrade to unlock code review, CI analysis, auto-apply, custom automations, and more.

Gitar

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes an Android startup crash caused by Realm attempting to mkfifo() under a temp directory located on FUSE-backed external storage by moving TMPDIR to internal app cache, while keeping Mono --jitmap perfmap support for native crash symbolication.

Changes:

  • Redirect Android TMPDIR from external storage to internal cache (/data/user/0/.../cache) to allow Realm FIFO creation.
  • Update inline documentation/comments in the Android project and native crash handler to reflect the new temp/perfmap location and rationale.
  • Remove committed diagnostic/build artifacts under build_test/.

Reviewed changes

Copilot reviewed 5 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
osu.Android/osu.Android.csproj Updates the <AndroidEnvironment> comment to reflect TMPDIR moving to internal cache and the Realm FIFO constraint.
osu.Android/mono.env Changes TMPDIR to internal cache and documents why external storage breaks Realm mkfifo() notifiers.
osu.Android/Native/crash_handler.cpp Updates perfmap/TMPDIR documentation to match the new internal-cache TMPDIR configuration.
build_test/archive.zip Removes diagnostic capture artifact.
build_test/CMakeFiles/cmake.check_cache Removes generated CMake artifact.
build_test/CMakeCache.txt Removes generated CMake cache.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 264 to +268
// Candidate directories, in priority order. The dir containing g_logPath
// is checked first so a build that sets `TMPDIR=<external-files-dir>`
// (the recommended config) finds its perfmap immediately.
// (external files dir) is checked first as a historical fallback, but
// current builds set TMPDIR to the app's internal cache dir (FUSE-backed
// external storage cannot host the FIFOs Realm needs — see mono.env), so
// the perfmap normally lives at $TMPDIR/perf-<pid>.map.

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With TMPDIR now recommended to point to internal cache, ensurePerfmapLoaded() will usually fail the first lookup attempt in the external-files log directory before trying $TMPDIR. Since this runs in the crash handler, consider reordering the candidate directories to check getenv("TMPDIR") first (and only fall back to the log dir), to reduce crash-time syscalls and simplify the “priority order” comment.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants